解决方式
一个请求最大为100MB
spring:
servlet:
multipart:
max-request-size: 100MB
分析过程
前提
某天突然发现来了这样得一个需求, 将图片变为base64 ,有两个服务,一个是a服务,一个是b服务,在a中上传图片,并且转换图片格式位base64,在通过fegin调用 b服务,b服务在做相关得操作,遇到了下面得两个问题
fegin 调用得时候,采用post得方式,得将base64得字符串放在请求体中Undertow 能接受得请求体得大小
feign调用得这个废了好大得事情,最后发现了,不仅要指定请求方式,还得添加 @RequestBody 注解,这就很离谱,看下面得一个列子
@RequestMapping(value = "/test", method = RequestMethod.POST)
Map test(@RequestBody JSONObject request);
返回正文,看看第二个问题,我是按照下面得来分析
springboot 得web模块,那肯定得从 DispatcherServlet中得 doDispatch 开始,我就一路断点进去了。 然后一路debug走,具体是怎么走得,这个是这样操作得首先开启debug日志看到一个方法,先F8过去,看看debug日志里面有没有报错,有得话,那就这个方法继续进去了。 按照这个方法,就能找到问题出现在哪里 下面是我debug得调用栈 问题就出现在了下面得代码 错误就是在这里抛出得,第106行用红框圈出来得代码。如果这里得 maxEntitySize < (state & MASK_COUNT) 就会进入这个 if 块里面 那肯定就得很注意这几个了exchange.getMaxEntitySize()stateMASK_COUNT 首先 这个state是参数是从哪里来得。 还是根据调用栈得顺序,按个往上走,看哪里能用得到。
可以看到 在这里给state赋值了,看这里写的意思是,state得值为请求头里面得 Content-Length 得值,至于是不是,各位可以继续往下走走看看哈。我在这里就不走了。
那么回过头 再来看看 MASK_COUNT是从哪里来得。一看这个玩意,一眼就能看出,是一个常量。点一下看看,就有下面得了 那这个值是多少呢? 计算一下看看 明了了吧。 在来看看 exchange.getMaxEntitySize() 方法,其实就是 httpServerExchange中得maxEntitySize属性。 点进去看看 那这个值是在哪里给得呢。 点一下看看,发现了两个地方
一个是构造函数 一个是set方法 那就在这里各自打一个断点,然后重新跑一遍看看 看看这个值是在哪里设置得 先是看看构造方法 通过调用栈可以看得到,那就看看 httpReadListener里面得 maxEntitySize 属性是在哪里取值得,点一下看看 看到了,在这里 那还是老套路,计算一下,看看这个值是多少。 直接就-1,就很离谱, 在多说一点哦, 之前看到有人说配置下面得 那这个值在Undertow 里面到底是什么呢? 其实是这个值,看到了哦,和maxEntitySize 没有关系,至于 maxRequestSize 是个啥,有啥作用,我没看,等我之后有时间了看看在写写
在来看看 set方法 看看调用栈得顺序,找到了它set 得时候,如果稍微仔细看得话,思考思考,这里是调用 exchange对象,那这个对象肯定已经new出来,那new出来了肯定会调用它得构造方法,那就说明,之前构造方法 给得 maxEntitySize是没有用得,在这里是会覆盖掉得,那继续看看 这个info 里面是干了啥。 可以看到,从info 里面进去,计算一下, 得到得是 dispatchServlet,获得得 maxRequestSize 其实就是得到了 dispatchServlet里面得 配置 答案已经慢慢出来了,但是还是可以点进去看看, 继续可以看到这里已经设置了,请求体得大小,在看看 multipartConfig对象,是个啥子玩意 看到了吧,答案已经出来了, exchange 中得 maxEntitySize 得大小 取得是 servlet 中配置得 maxRequestSize 得大小 可以看到 在servlet中 maxRequestSize 默认是-1 ,表示无限大,在看看spring帮我们配置得时候得大小 spring 中默认得是10mb ,ok了。到这里我的分析就结束了。
|